﻿using EntityFramework.Caching;
using EntityFramework.Extensions;
using RXY_Mall.Api.Common;
using RXY_Mall.Api.Models;
using RXY_Mall.Core;
using AliyunSmsSDK;
using RXY_Mall.Core.Tool;
using RXY_Mall.Data;
using RXY_Mall.Domain;
using RXY_Mall.Services;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using RXY_Mall.Services.User;

namespace RXY_Mall.Api.Controllers
{
    /// <summary>
    /// 资产接口
    /// </summary>
    [RoutePrefix("Finance")]
    [ApiSecurityFilter]
    public class FinanceController : BaseApiController
    {
        private RXY_MallContext db;
        private UserService userService;

        public FinanceController()
        {
            db = new RXY_MallContext();
            userService = new UserService();
        }

        #region 银行卡
        /// <summary>
        /// 添加银行卡
        /// </summary>
        [HttpPost]
        [Route("AddBankCard")]
        public async Task<Response<string>> AddBankCard(AddBankCardInput input)
        {
            Response<string> result = new Response<string>();
            result.code = 0;
            try
            {
                var user = await db.gw_users.FindAsync(input.user_id);
                if (user == null)
                {
                    result.msg = "用户不存在";
                    return result;
                }
                //判断持卡人名是否与注册真实名相符
                if (user.real_name != input.account_holder.Trim())
                {
                    result.msg = "持卡人须与会员账号登记姓名一致";
                    return result;
                }

                var bankcard = new gw_finance_bankcard()
                {
                    user_id = input.user_id,
                    bank_name = input.bank_name,
                    card_no = input.card_no,
                    account_holder = input.account_holder,
                    bank_address = input.bank_address,
                    bank_branch = input.bank_branch,
                    add_time = DateTime.Now,
                    mobile = input.mobile,
                    status = 1,
                    remark = input.remark
                };
                db.gw_finance_bankcards.Add(bankcard);
                int row = await db.SaveChangesAsync();

                if (row > 0)
                {
                    result.code = 1;
                    result.msg = "添加成功";
                }
                else
                {
                    result.msg = "添加失败";
                }
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 删除银行卡
        /// </summary>
        [HttpPost]
        [Route("DeleteBankCard")]
        public async Task<Response<string>> DeleteBankCard(DeleteBankCardInput input)
        {
            Response<string> result = new Response<string>();
            result.code = 0;
            try
            {
                var bankcard = await db.gw_finance_bankcards.FindAsync(input.bank_card_id);
                if (bankcard == null)
                {
                    result.msg = "银行卡不存在";
                    return result;
                }
                if (bankcard.user_id != input.user_id)
                {
                    result.msg = "不是自己的银行卡";
                    return result;
                }

                db.gw_finance_bankcards.Remove(bankcard);
                int row = await db.SaveChangesAsync();

                if (row > 0)
                {
                    result.code = 1;
                    result.msg = "删除成功";
                }
                else
                {
                    result.msg = "删除失败";
                }
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 获取银行卡
        /// </summary>
        [HttpGet]
        [Route("GetBankCardList")]
        public async Task<Response<List<BankCardOutput>>> GetBankCardList(int user_id)
        {
            Response<List<BankCardOutput>> result = new Response<List<BankCardOutput>>();
            try
            {
                var lstBankCard = await db.gw_finance_bankcards.Where(a => a.user_id == user_id && a.status == 1).AsNoTracking().ToListAsync();
                List<BankCardOutput> output = new List<BankCardOutput>();
                if (lstBankCard != null && lstBankCard.Count > 0)
                {

                    foreach (var item in lstBankCard)
                    {
                        BankCardOutput bankcard = new BankCardOutput()
                        {
                            bank_card_id = item.id,
                            account_holder = item.account_holder,
                            bank_address = item.bank_address,
                            bank_branch = item.bank_branch,
                            card_no = StringHelper.HideBankCard(item.card_no),
                            bank_name = item.bank_name,
                            remark = item.remark,
                        };
                        output.Add(bankcard);
                    }
                }
                result.code = 1;
                result.data = output;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        #endregion

        #region 提现
        /// <summary>
        /// 提现申请（第4批）
        /// </summary>
        [HttpPost]
        [Route("AddWithdraw")]
        public async Task<Response<string>> AddWithdraw(AddWithdrawInput input)
        {
            Response<string> result = new Response<string>();
            result.code = 0;
            try
            {
                //判断条件
                if (input.money <= 0)
                {
                    result.msg = "请输入提现金额";
                    return result;
                }

                //判断支付密码
                string password = input.pay_password;
                var payPassword = await db.gw_user_passwords.FirstOrDefaultAsync(p => p.user_id == input.user_id && p.type == 1);
                if (payPassword == null)
                {
                    result.msg = "请设置支付密码";
                    return result;
                }
                if (!payPassword.password.Equals(EncryptionHelper.EncryptText(password)))
                {
                    result.msg = "支付密码不正确";
                    return result;
                }

                //用户权限
                var user = await db.gw_users.Include(u => u.gw_finance_property).FirstOrDefaultAsync(u => u.id == input.user_id);
                if (user == null)
                {
                    result.msg = "用户不存在";
                    return result;
                }
                if (user.status == 2)
                {
                    result.msg = "用户加入黑名单";
                    return result;
                }

                if (input.money < 100)
                {
                    result.msg = "提现金额不能小于100元";
                    return result;
                }
                if (input.money > 50000)
                {
                    result.msg = "提现金额不能大于5万元";
                    return result;
                }

                if (user.gw_finance_property.balance < input.money)
                {
                    result.msg = "提现金额必须小于用户余额";
                    return result;
                }

                var fee = input.money * 0.01m;
                var amount = input.money + fee;
                if (user.gw_finance_property.balance < amount)
                {
                    fee = user.gw_finance_property.balance * 0.01m;
                    amount = user.gw_finance_property.balance - fee;

                    result.msg = string.Format("剩余零钱不足以支付提现手续费￥{0},当前最大可提现金额为￥{1}", fee, amount);
                    return result;
                }

                var bankcard = await db.gw_finance_bankcards.FindAsync(input.bank_card_id);
                if (bankcard == null)
                {
                    result.msg = "请选择银行卡";
                    return result;
                }
                if (bankcard.user_id != input.user_id)
                {
                    result.msg = "该银行卡不是自己的";
                    return result;
                }
                if (bankcard.account_holder != user.real_name)
                {
                    result.msg = "持卡人须与会员账号登记姓名一致";
                    return result;
                }
                //添加订单
                var order_no = string.Format("M000{0}", Utils.GetOrderNumber());

                gw_finance_withdraw withdraw = new gw_finance_withdraw()
                {
                    order_no = order_no,
                    money = input.money,
                    user_id = user.id,
                    status = 1,
                    add_time = DateTime.Now,
                    type = 1,
                    card_no = bankcard.card_no,
                    bank_name = bankcard.bank_name,
                    bank_address = bankcard.bank_address,
                    bank_branch = bankcard.bank_branch,
                    account_holder = bankcard.account_holder,
                    mobile = bankcard.mobile,
                    service_fee = fee,
                    amount = input.money + fee,
                };

                db.gw_finance_withdraws.Add(withdraw);

                user.gw_finance_property.balance -= withdraw.amount;
                db.Entry(user.gw_finance_property).Property(u => u.balance).IsModified = true;

                var gw_finance_property_log = new gw_finance_property_log()
                {
                    add_time = DateTime.Now,
                    last_value = user.gw_finance_property.balance,
                    remark = "提现",
                    type = (int)PaymentType.Expense,
                    user_id = user.id,
                    value = withdraw.amount,
                    order_no = withdraw.order_no,
                    trade_type = (int)TradeType.提现,
                    currency = (byte)Currencies.Balance,
                };
                db.gw_finance_property_logs.Add(gw_finance_property_log);

                int row = await db.SaveChangesAsync();

                result.code = 1;
                result.msg = "提现成功";

            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 提现记录（第4批）
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="page_index">页码</param>
        /// <param name="page_size">页数</param>
        [HttpGet]
        [Route("GetWithdrawList")]
        public Response<PagedList<GetWithdrawListOutput>> GetWithdrawList(int user_id, int page_index = 1, int page_size = 20)
        {
            Response<PagedList<GetWithdrawListOutput>> result = new Response<PagedList<GetWithdrawListOutput>>();
            try
            {
                var lstDrawalRecord = db.gw_finance_withdraws
                    .Where(r => r.user_id == user_id && r.type == 1)
                    .Select(w => new GetWithdrawListOutput()
                    {
                        card_no = w.card_no,
                        bank_name = w.bank_name,
                        bank_address = w.bank_address,
                        bank_branch = w.bank_branch,
                        dismiss_reason = w.dismiss_reason,
                        money = w.money,
                        amount = w.amount,
                        account_holder = w.account_holder,
                        remark = w.remark,
                        service_fee = w.service_fee,
                        status = w.status,
                        withdraw_id = w.id,
                        add_time = w.add_time,
                        update_time = w.update_time,
                    })
                    .OrderByDescending(r => r.add_time)
                    .AsNoTracking();

                PagedList<GetWithdrawListOutput> pageList = new PagedList<GetWithdrawListOutput>(lstDrawalRecord, page_index, page_size);
                if (pageList != null)
                {
                    foreach (var item in pageList)
                    {
                        item.withdraw_time = TimeHelper.GetTimeStamp(item.add_time);
                        item.complete_time = TimeHelper.GetTimeStamp(item.update_time);
                        item.card_no = StringHelper.HideBankCard(item.card_no);
                    }
                }
                result.data = pageList;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 提现详情（第4批）
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="withdraw_id">提现ID</param>
        [HttpGet]
        [Route("GetWithdraw")]
        public async Task<Response<GetWithdrawListOutput>> GetWithdraw(int user_id, int withdraw_id)
        {
            Response<GetWithdrawListOutput> result = new Response<GetWithdrawListOutput>();
            try
            {
                var output = await db.gw_finance_withdraws
                    .Where(r => r.user_id == user_id && r.type == 1 && r.id == withdraw_id)
                    .Select(w => new GetWithdrawListOutput()
                    {
                        card_no = w.card_no,
                        bank_name = w.bank_name,
                        bank_address = w.bank_address,
                        bank_branch = w.bank_branch,
                        dismiss_reason = w.dismiss_reason,
                        money = w.money,
                        amount = w.amount,
                        account_holder = w.account_holder,
                        remark = w.remark,
                        service_fee = w.service_fee,
                        status = w.status,
                        withdraw_id = w.id,
                        add_time = w.add_time,
                        update_time = w.update_time,
                    })
                    .FirstOrDefaultAsync();


                result.data = output;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        #endregion

        #region 交易记录
        /// <summary>
        /// 获得交易记录（第4批）
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="currency_type">货币类型</param>
        /// <param name="page_index">第几页</param>
        /// <param name="page_size">每页多少</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetTradeLogs")]
        public Response<IPagedList<GetTradeLogsOutput>> GetTradeLogs(int user_id, Currencies currency_type = Currencies.Balance, int page_index = 1, int page_size = 20)
        {
            Response<IPagedList<GetTradeLogsOutput>> result = new Response<IPagedList<GetTradeLogsOutput>>();
            try
            {
                var source = db.gw_finance_property_logs
                    .Where(l => l.user_id == user_id && l.currency == (int)currency_type)
                    .Select(l => new GetTradeLogsOutput()
                    {
                        order_no = l.order_no,
                        type = (PaymentType)l.type,
                        add_time = l.add_time,
                        last_value = l.last_value,
                        _trade_type = l.trade_type,
                        value = l.value,
                        currency = (Currencies)l.currency,
                        remark = l.remark,
                    });

                source = source.OrderByDescending(s => s.add_time);
                IPagedList<GetTradeLogsOutput> pageList = new PagedList<GetTradeLogsOutput>(source, page_index, page_size);

                foreach (var item in pageList)
                {
                    item.trade_time = TimeHelper.GetTimeStamp(item.add_time);
                    item.remain_value = item.last_value.ToString("0.00");
                    item.trade_value = item.value.ToString("0.00");
                    item.trade_type = ((TradeType)item._trade_type).ToString();
                }

                result.data = pageList;
                result.code = 1;
                return result;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        #endregion

        #region 弟子交易记录
        /// <summary>
        /// 弟子信息
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetChildInfo")]
        public async Task<Response<GetChildInfoOutput>> GetChildInfo(int user_id)
        {
            Response<GetChildInfoOutput> result = new Response<GetChildInfoOutput>();
            result.code = 0;

            try
            {
                GetChildInfoOutput output = new GetChildInfoOutput();
                output.child_count = 0;
                output.trade_volume = "0";

                result.code = 1;
                var user = await db.gw_users.Include(u => u.children).FirstOrDefaultAsync(u => u.id == user_id);
                if (user.children == null)
                {
                    result.data = output;
                    return result;
                }
                output.child_count = user.children.Count;

                var childrenIds = user.children.Select(u => u.id).ToList();
                childrenIds.Add(user_id);

                //总交易额
                var trade_volume = await db.gw_finance_trade_logs.Where(l => childrenIds.Contains(l.user_id)).SumAsync(l => (decimal?)l.amount);
                if (trade_volume == null)
                {
                    trade_volume = 0m;
                }
                //获得成为掌门人的粉丝
                var users = await db.gw_user_upgrades.Where(u => u.from_parent_id == user_id).ToListAsync();

                foreach (var item in users)
                {
                    //成为掌门人之前的交易额
                    var trade = await db.gw_finance_trade_logs.Where(l => l.user_id == item.user_id && l.add_time < item.add_time).SumAsync(l => l.amount);
                    trade_volume += trade;
                }

                output.trade_volume = trade_volume.ToString();

                result.data = output;
                result.code = 1;
                return result;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }

            return result;
        }

        /// <summary>
        /// 弟子交易流水
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="page_index">页码</param>
        /// <param name="page_size">页数</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetChildTradeLogs")]
        public Response<IPagedList<GetChildTradeLogsOutput>> GetChildTradeLogs(int user_id, int page_index = 1, int page_size = 20)
        {
            Response<IPagedList<GetChildTradeLogsOutput>> result = new Response<IPagedList<GetChildTradeLogsOutput>>();

            try
            {
                result.code = 1;

                //var user = db.gw_users.Include(u => u.children).FirstOrDefault(u => u.id == user_id);
                //if (user.children == null)
                //{
                //    result.data = null;
                //    return result;
                //}
                //var childrenIds = user.children.Select(u => u.id).ToList();

                var childrenIds = db.gw_users.Where(u => u.parent_id == user_id).Select(u => u.id).ToList();
                childrenIds.Add(user_id);

                //交易流水
                var logs = db.gw_finance_trade_logs.Include(l => l.gw_user)
                    .Where(l => childrenIds.Contains(l.user_id))
                    .Select(item => new GetChildTradeLogsOutput()
                    {
                        add_time = item.add_time,
                        amount = item.amount,
                        user_name = item.gw_user.name,
                        nick_name = item.gw_user.nick_name,
                        user_logo = item.gw_user.logo,
                    });
                logs = logs.OrderByDescending(l => l.add_time);

                var pageList = new PagedList<GetChildTradeLogsOutput>(logs, page_index, page_size);
                foreach (var item in pageList)
                {
                    if (string.IsNullOrEmpty(item.nick_name))
                    {
                        item.user_name = StringHelper.HideMobile(item.user_name);
                    }
                    else
                    {
                        item.user_name = item.nick_name;
                    }
                    item.trade_add_time = TimeHelper.GetTimeStamp(item.add_time);
                }

                result.data = pageList;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        #endregion

        #region 红包
        /// <summary>
        /// 红包信息
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRedpacketInfo")]
        public async Task<Response<GetRedpacketInfoOutput>> GetRedpacketInfo(int user_id)
        {
            Response<GetRedpacketInfoOutput> result = new Response<GetRedpacketInfoOutput>();
            result.code = 0;

            try
            {
                GetRedpacketInfoOutput output = new GetRedpacketInfoOutput();
                output.redpacket_count = 0;
                output.trade_volume = "0";

                var date = DateTime.Now;
                output = await db.gw_finance_redpackets
                    .Where(l => l.user_id == user_id)
                    .GroupBy(l => l.user_id)
                    .Select(l => new GetRedpacketInfoOutput()
                    {
                        trade_volume = l.Where(item => item.is_acquire).Sum(item => item.amount).ToString(),
                        redpacket_count = l.Count(item => item.is_acquire || item.expire_time < date),
                    }).FirstOrDefaultAsync();

                result.data = output;
                result.code = 1;
                return result;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }

            return result;
        }

        /// <summary>
        /// 获得今天红包列表
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="page_index">页码</param>
        /// <param name="page_size">页数</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetTodayRedpacketList")]
        public Response<IPagedList<GetRedpacketOutput>> GetTodayRedpacketList(int user_id, int page_index = 1, int page_size = 20)
        {
            return GetRedpackets(user_id, 2, page_index, page_size);
        }

        /// <summary>
        /// 获得红包列表
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="page_index">页码</param>
        /// <param name="page_size">页数</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRedpacketList")]
        public Response<IPagedList<GetRedpacketOutput>> GetRedpacketList(int user_id, int page_index = 1, int page_size = 20)
        {
            return GetRedpackets(user_id, 0, page_index, page_size);
        }

        /// <summary>
        /// 获得红包
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="type">类型 0-今日红包 1-红包进贡列表 2-过期</param>
        /// <param name="page_index">页码</param>
        /// <param name="page_size">页数</param>
        /// <returns></returns>
        private Response<IPagedList<GetRedpacketOutput>> GetRedpackets(int user_id, int type = 0, int page_index = 1, int page_size = 20)
        {
            Response<IPagedList<GetRedpacketOutput>> result = new Response<IPagedList<GetRedpacketOutput>>();
            try
            {
                var redpackets = db.gw_finance_redpackets
                    .Include(r => r.oppositer)
                    .Where(r => r.user_id == user_id);

                if (type == 2)
                {
                    var date = DateTime.Now;
                    redpackets = redpackets.Where(r => r.expire_time > date);
                }
                else
                {
                    var date = DateTime.Now;
                    redpackets = redpackets.Where(r => r.is_acquire || r.expire_time < date);
                }

                var source = redpackets
                    .Select(w => new GetRedpacketOutput()
                    {
                        nick_name = w.oppositer.nick_name,
                        redpacket_id = w.id,
                        add_time = w.add_time,
                        redpacket_type = (RedpacketType)w.type,
                        user_logo = w.oppositer.logo,
                        user_name = w.oppositer.name,
                        remark = w.remark,
                        acquire_time = w.acquire_time,
                        is_acquire = w.is_acquire,
                        value = w.amount,
                        expire_time = w.expire_time,
                    })
                    .OrderByDescending(r => r.add_time)
                    .AsNoTracking();

                IPagedList<GetRedpacketOutput> pageList = new PagedList<GetRedpacketOutput>(source, page_index, page_size);
                if (pageList != null)
                {
                    foreach (var item in pageList)
                    {
                        if (!string.IsNullOrEmpty(item.nick_name))
                        {
                            item.user_name = item.nick_name;
                        }
                        else
                        {
                            item.user_name = StringHelper.HideMobile(item.user_name);
                        }
                        item.acquire_red_time = TimeHelper.GetTimeStamp(item.acquire_time);
                        item.add_red_time = TimeHelper.GetTimeStamp(item.add_time);
                        item.expire_red_time = TimeHelper.GetTimeStamp(item.expire_time);
                        if (!item.is_acquire)
                        {
                            item.value = 0;
                        }
                    }
                }
                result.data = pageList;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 获得红包详情
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="redpacket_id">红包ID</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetRedpacket")]
        public async Task<Response<GetRedpacketOutput>> GetRedpacket(int user_id, int redpacket_id)
        {
            Response<GetRedpacketOutput> result = new Response<GetRedpacketOutput>();
            try
            {
                var output = await db.gw_finance_redpackets
                    .Include(r => r.oppositer)
                    .Include(r => r.gw_finance_redpacket_subsidy)
                    .Where(r => r.user_id == user_id)
                    .Select(item => new GetRedpacketOutput()
                    {
                        nick_name = item.oppositer.nick_name,
                        redpacket_id = item.id,
                        add_time = item.add_time,
                        redpacket_type = (RedpacketType)item.type,
                        user_logo = item.oppositer.logo,
                        user_name = item.oppositer.name,
                        remark = item.remark,
                        acquire_time = item.acquire_time,
                        expire_time = item.expire_time,
                        is_acquire = item.is_acquire,
                        value = item.amount,
                        total_cycle = (int?)item.gw_finance_redpacket_subsidy.total_cycle
                    })
                    .FirstOrDefaultAsync(r => r.redpacket_id == redpacket_id);
                if (output != null)
                {
                    if (string.IsNullOrEmpty(output.nick_name))
                    {
                        output.user_name = StringHelper.HideMobile(output.user_name);
                    }
                    else
                    {
                        output.user_name = output.nick_name;
                    }
                    output.acquire_red_time = TimeHelper.GetTimeStamp(output.acquire_time);
                    output.expire_red_time = TimeHelper.GetTimeStamp(output.expire_time);
                    output.add_red_time = TimeHelper.GetTimeStamp(output.add_time);
                    if (!output.is_acquire)
                    {
                        output.value = 0;
                    }
                }

                result.data = output;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 领取红包（第4批）
        /// </summary>
        [HttpPost]
        [Route("AcquireRedpacket")]
        public async Task<Response<bool>> AcquireRedpacket(AcquireRedpacketInput input)
        {
            Response<bool> result = new Response<bool>();
            result.code = 0;
            try
            {
                var redpacket = await db.gw_finance_redpackets
                    .Include(r => r.gw_order)
                    .Include(r => r.gw_order.gw_order_goods)
                    .Include(r => r.gw_order_group_user)
                    .Include(r => r.gw_finance_redpacket_subsidy)
                    .FirstOrDefaultAsync(o => o.id == input.redpacket_id);

                if (redpacket.user_id != input.user_id)
                {
                    result.msg = "非法访问";
                    return result;
                }

                if (redpacket == null)
                {
                    result.msg = "红包不存在";
                    return result;
                }

                var date = DateTime.Now;
                if (!redpacket.is_acquire && redpacket.expire_time < date)
                {
                    result.msg = "已过期";
                    return result;
                }

                if (redpacket.is_acquire)
                {
                    result.msg = "已领取";
                    return result;
                }

                //红包记录
                redpacket.is_acquire = true;
                redpacket.acquire_time = DateTime.Now;
                db.Entry(redpacket).Property(o => o.is_acquire).IsModified = true;
                db.Entry(redpacket).Property(o => o.acquire_time).IsModified = true;

                if (redpacket.gw_order_group_user != null)
                {
                    //拼单获取时间
                    redpacket.gw_order_group_user.acquire_time = DateTime.Now;
                    db.Entry(redpacket.gw_order_group_user).Property(p => p.acquire_time).IsModified = true;
                }

                if (redpacket.type == (int)RedpacketType.补贴卡)
                {
                    var user = await db.gw_users
                        .Include(u => u.gw_finance_property)
                        .FirstOrDefaultAsync(u => u.id == input.user_id);

                    //补贴一期
                    redpacket.gw_finance_redpacket_subsidy.status = 1;
                    redpacket.gw_finance_redpacket_subsidy.remain_cycle -= 1;
                    db.Entry(redpacket.gw_finance_redpacket_subsidy).Property(o => o.status).IsModified = true;
                    db.Entry(redpacket.gw_finance_redpacket_subsidy).Property(o => o.remain_cycle).IsModified = true;

                    var mode = (redpacket.amount * 100m) % redpacket.gw_finance_redpacket_subsidy.total_cycle;
                    var value = 0m;
                    if (mode == 0)
                    {
                        value = redpacket.amount / redpacket.gw_finance_redpacket_subsidy.total_cycle;
                    }
                    else
                    {
                        value = (redpacket.amount - mode / 100m) / redpacket.gw_finance_redpacket_subsidy.total_cycle;
                    }

                    //补贴记录
                    gw_finance_redpacket_subsidy_item item = new gw_finance_redpacket_subsidy_item()
                    {
                        add_time = DateTime.Now,
                        month = 1,
                        subsidy_id = redpacket.gw_finance_redpacket_subsidy.id,
                        value = value,
                    };
                    db.gw_finance_subsidy_items.Add(item);

                    //余额
                    user.gw_finance_property.balance += value;
                    db.Entry(user.gw_finance_property).Property(p => p.balance).IsModified = true;

                    //余额记录
                    var log = new gw_finance_property_log()
                    {
                        add_time = DateTime.Now,
                        order_no = redpacket.gw_order.order_no,
                        trade_type = (int)TradeType.补贴卡,
                        currency = (byte)Currencies.Balance,
                        last_value = user.gw_finance_property.balance,
                        remark = TradeType.补贴卡.ToString(),
                        type = (int)PaymentType.Income,
                        user_id = redpacket.user_id,
                        value = value,
                    };
                    db.gw_finance_property_logs.Add(log);

                    await db.SaveChangesAsync();

                }
                else
                {
                    var user = await db.gw_users
                        .Include(u => u.gw_finance_property)
                        .FirstOrDefaultAsync(u => u.id == input.user_id);

                    //余额
                    user.gw_finance_property.balance += redpacket.amount;
                    db.Entry(user.gw_finance_property).Property(p => p.balance).IsModified = true;

                    //余额记录--拼手气红包
                    var log = new gw_finance_property_log()
                    {
                        add_time = DateTime.Now,
                        order_no = redpacket.gw_order.order_no,
                        trade_type = redpacket.type,
                        currency = (byte)Currencies.Balance,
                        last_value = user.gw_finance_property.balance,
                        remark = ((TradeType)redpacket.type).ToString(),
                        type = (int)PaymentType.Income,
                        user_id = redpacket.user_id,
                        value = redpacket.amount,
                    };
                    db.gw_finance_property_logs.Add(log);

                    List<int> lst = new List<int>();
                    lst.Add((int)TradeType.拼手气鼓励金红包);
                    lst.Add((int)TradeType.购物鼓励金红包);

                    //进贡红包
                    var redpacket2 = 0m;
                    //掌门人红包
                    var redpacket3 = 0m;

                    var parent_id = user.parent_id;
                    if (parent_id != null && lst.Contains(redpacket.type))
                    {
                        //师傅进贡
                        var parent = await db.gw_users.FindAsync(parent_id);
                        if (parent.grade != (int)UserGrade.Ordinary)
                        {
                            //一级10%
                            redpacket2 = redpacket.amount * 0.1m;

                            //进贡红包
                            gw_finance_redpacket finance_redpacket = new gw_finance_redpacket()
                            {
                                add_time = DateTime.Now,
                                expire_time = DateTime.Now.AddDays(1),
                                oppositer_id = input.user_id,
                                order_group_user_id = null,
                                order_id = redpacket.order_id,
                                type = (int)RedpacketType.好友进贡红包,
                                user_id = parent.id,
                                amount = redpacket2,
                                remark = RedpacketType.好友进贡红包.ToString(),
                            };
                            db.gw_finance_redpackets.Add(finance_redpacket);

                            //红包消息
                            gw_message messageRed = new gw_message()
                            {
                                add_time = DateTime.Now,
                                title = RedpacketType.好友进贡红包.ToString(),
                                summary = RedpacketType.好友进贡红包.ToString(),
                                status = 1,
                                type = (int)MessageType.Redpacket,
                                user_id = parent.id,
                                company_id = CompanyId,
                            };
                            gw_message_rule_redpacket messageRuleRed = new gw_message_rule_redpacket()
                            {
                                redpacket_type = (int)RedpacketType.好友进贡红包,
                                gw_finance_redpacket = finance_redpacket,
                            };
                            messageRed.gw_message_rule_redpacket = messageRuleRed;

                            db.gw_messages.Add(messageRed);

                            //余额
                            user.gw_finance_property.balance -= redpacket2;
                            db.Entry(user.gw_finance_property).Property(p => p.balance).IsModified = true;

                            //余额记录
                            var log2 = new gw_finance_property_log()
                            {
                                add_time = DateTime.Now,
                                order_no = redpacket.gw_order.order_no,
                                trade_type = (int)TradeType.好友进贡红包,
                                currency = (byte)Currencies.Balance,
                                last_value = user.gw_finance_property.balance,
                                remark = TradeType.好友进贡红包.ToString(),
                                type = (int)PaymentType.Expense,
                                user_id = redpacket.user_id,
                                value = redpacket2,
                            };
                            db.gw_finance_property_logs.Add(log2);

                        }

                        //掌门人进贡
                        var chief = userService.GetGuildChief((int)parent_id);
                        if (chief != null && chief.id != parent_id && chief.grade == (byte)UserGrade.GuildChief)
                        {
                            //5%
                            redpacket3 = redpacket.amount * 0.05m;

                            //进贡红包
                            gw_finance_redpacket finance_redpacket = new gw_finance_redpacket()
                            {
                                add_time = DateTime.Now,
                                expire_time = DateTime.Now.AddDays(1),
                                oppositer_id = input.user_id,
                                order_group_user_id = null,
                                order_id = redpacket.order_id,
                                type = (int)RedpacketType.好友进贡红包,
                                user_id = chief.id,
                                amount = redpacket3,
                                remark = RedpacketType.好友进贡红包.ToString(),
                            };
                            db.gw_finance_redpackets.Add(finance_redpacket);

                            //红包消息
                            gw_message messageRed = new gw_message()
                            {
                                add_time = DateTime.Now,
                                title = RedpacketType.好友进贡红包.ToString(),
                                summary = RedpacketType.好友进贡红包.ToString(),
                                status = 1,
                                type = (int)MessageType.Redpacket,
                                user_id = chief.id,
                            };
                            gw_message_rule_redpacket messageRuleRed = new gw_message_rule_redpacket()
                            {
                                redpacket_type = (int)RedpacketType.好友进贡红包,
                                gw_finance_redpacket = finance_redpacket,
                            };
                            messageRed.gw_message_rule_redpacket = messageRuleRed;

                            db.gw_messages.Add(messageRed);

                            //余额
                            user.gw_finance_property.balance -= redpacket3;
                            db.Entry(user.gw_finance_property).Property(p => p.balance).IsModified = true;

                            //余额记录
                            var log3 = new gw_finance_property_log()
                            {
                                add_time = DateTime.Now,
                                order_no = redpacket.gw_order.order_no,
                                trade_type = (int)TradeType.好友进贡红包,
                                currency = (byte)Currencies.Balance,
                                last_value = user.gw_finance_property.balance,
                                remark = TradeType.好友进贡红包.ToString(),
                                type = (int)PaymentType.Expense,
                                user_id = redpacket.user_id,
                                value = redpacket3,
                            };
                            db.gw_finance_property_logs.Add(log3);

                        }
                    }

                    await db.SaveChangesAsync();


                }

                result.code = 1;
                result.data = true;
                result.msg = "领取成功";
                return result;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        #endregion

        #region 补贴卡

        /// <summary>
        /// 获得补贴卡列表
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="page_index">页码</param>
        /// <param name="page_size">页数</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetSubsidyList")]
        public Response<IPagedList<GetSubsidyListOutput>> GetSubsidyList(int user_id, int page_index = 1, int page_size = 20)
        {
            Response<IPagedList<GetSubsidyListOutput>> result = new Response<IPagedList<GetSubsidyListOutput>>();
            try
            {
                var redpackets = db.gw_finance_subsidies
                    .Include(r => r.gw_finance_redpacket)
                    .Where(r => r.gw_finance_redpacket.user_id == user_id && r.status == 1);

                var source = redpackets
                    .Select(w => new GetSubsidyListOutput()
                    {
                        acquire_time = w.gw_finance_redpacket.acquire_time,
                        redpacket_id = w.gw_finance_redpacket.id,
                        is_acquire = w.gw_finance_redpacket.is_acquire,
                        amount = w.gw_finance_redpacket.amount,
                        remain_cycle = w.remain_cycle,
                        total_cycle = w.total_cycle,

                    })
                    .OrderByDescending(r => r.acquire_time)
                    .AsNoTracking();

                IPagedList<GetSubsidyListOutput> pageList = new PagedList<GetSubsidyListOutput>(source, page_index, page_size);
                if (pageList != null)
                {
                    foreach (var item in pageList)
                    {
                        item.acquire_subsidytime = TimeHelper.GetTimeStamp(item.acquire_time);
                    }
                }
                result.data = pageList;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        /// <summary>
        /// 获得补贴详情
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="redpacket_id">红包ID</param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetSubsidy")]
        public Response<GetSubsidyOutput> GetSubsidy(int user_id, int redpacket_id)
        {
            Response<GetSubsidyOutput> result = new Response<GetSubsidyOutput>();
            try
            {
                var subsidy = db.gw_finance_subsidies
                    .Include(s => s.gw_finance_redpacket)
                    .Include(s => s.gw_finance_redpacket_subsidy_item)
                    .Where(r => r.id == redpacket_id && r.gw_finance_redpacket.user_id == user_id && r.status == 1)
                    .Select(w => new GetSubsidyOutput()
                    {
                        acquire_time = w.gw_finance_redpacket.acquire_time,
                        redpacket_id = w.id,
                        is_acquire = w.gw_finance_redpacket.is_acquire,
                        amount = w.gw_finance_redpacket.amount,
                        remain_cycle = w.remain_cycle,
                        total_cycle = w.total_cycle,

                        items = w.gw_finance_redpacket_subsidy_item.Select(item => new SubsidyItem()
                        {
                            add_time = item.add_time,
                            value = item.value,
                            month = item.month,

                        }).ToList(),

                    }).FirstOrDefault();
                if (subsidy == null)
                {
                    result.msg = "补贴不存在";
                    return result;
                }

                subsidy.acquire_subsidytime = TimeHelper.GetTimeStamp(subsidy.acquire_time);

                if (subsidy.items != null && subsidy.items.Count > 0)
                {
                    subsidy.items.ForEach(i => i.date = TimeHelper.GetTimeStamp(i.add_time));
                }

                result.data = subsidy;
                result.code = 1;
            }
            catch (Exception ex)
            {
                result.code = 2;
                result.msg = ex.Message;
                LogHelper.WriteLog(ex);
            }
            return result;
        }

        #endregion

    }
}
